/* eslint-disable */
import React, { PureComponent } from 'react';
import { Row, Col, Card, Button } from 'antd';

export default class Demo1 extends PureComponent {
  handleDemo1 = () => {
    for(var i = 0; i < 5; i++) {
      setTimeout(function() {
        console.log(Date.now(), i);  //  5, 5, ,5 ,5 , 5
      }, 1000)
    }
    console.log(Date.now(), i); // 立即执行;
  }

  handleDemo2 = () => {
    // for (var i = 0; i < 5; i += 1) { // 输出还是 5, 5, 5, 5, 5
    for (let i = 0; i < 5; i += 1) {  // let 在 for 循环中，形成了局部作用域;
      setTimeout(() => {
        console.log(new Date(), i); // 1, 2, 3, 4, 5;
      }, 1000);
    }
    // console.log(Date.now(), i); // 立即执行, 报错， i is undefined，不在局部作用域中;
  }

  handleDemo3 = () => {
    for(var i = 0; i < 5; i++) {
      // 形成闭包， 把 i 变量传入闭包--自执行函数， 保存起来;
      (function(j){
        setTimeout(function(){
          console.log(Date.now(), j);
        }, 1000);
      })(i)
    }
    console.log(Date.now(), i);
  }

  handleDemo4 = () => {
    // 利用函数传值，形成闭包，保存变量 i
    var count = function(j) {
      setTimeout(function() {
        console.log(Date.now(), j)
      }, 1000)
    }
    for(var i = 0; i < 5; i++) {
      count(i);
    }
    console.log(Date.now(), i);
  }

  // async 实现的 sleep 功能;
  handleDemo5 = async () => {
    var sleep = function(t) {
      return new Promise((resolve) => {
        setTimeout(resolve, t);
      })
    }
    var count = async function(t) {
      if (t !== 0) {
        await sleep(1000);
      }
      console.log(new Date(), t)
      //  await sleep(1000);
    }
    for(var i = 0; i < 5; i++) {
      await count(i);
    }
    await sleep(1000);
    console.log(new Date(), i);
    // setTimeout(function(){
    //   console.log(new Date(), 5)
    // }, 1000)
  }
  // ??? 不好的实践， 并不能保证 count(5) 是 for 循环之后的异步流程，只是取巧 setTimeout
  handleDemo51 = () => {
    var sleep = function(t) {
      return new Promise((resolve) => {
        setTimeout(resolve, t);
      })
    }
    var count = async function(t) {
      await sleep(1000 * t);
      console.log(new Date(), t)
    }
    for(var i = 0; i < 5; i++) {
      count(i);
    }
    //  console.log(Date.now(), i);
    //  setTimeout(function(){
    //    console.log(new Date(), 5)
    //  }, 1000)
    count(5)
  }

  handleDemo6 = () => {
    const promises = [];
    const count = function(t) {
      return new Promise((resolve) => {
        setTimeout(function() {
          console.log(new Date(), t)
          resolve(); // 不要忘了 resolve()
        }, t * 1000)
      })
    }
    for (var i = 0; i < 5; i++) {
      promises.push(count(i));
    }
    Promise.all(promises)
      .then((array) => {
        // console.log(array)
        setTimeout(function(){
          console.log(new Date(), i)
        }, 1000)
      })
      .catch(err => console.log(err))
  }

  render() {
    return (
      <Row>
        <Col>
          <Card title="闭包和for循环">
            <div>
              <h4>测试demo1: 最初的办法</h4>
              <Button type="primary"onClick={this.handleDemo1}>demo1:</Button>
            </div>
            <div>
              <h4>测试demo2: 利用let形成局部作用域</h4>
              <Button type="primary"onClick={this.handleDemo2}>demo1:</Button>
            </div>
            <div>
              <h4>测试demo3: for循环中的闭包: 自执行函数</h4>
              <Button type="primary"onClick={this.handleDemo3}>demo3:</Button>
            </div>
            <div>
              <h4>测试demo4: for循环中的闭包：函数传参</h4>
              <Button type="primary"onClick={this.handleDemo4}>demo4:</Button>
            </div>
            <div>
              <h4>测试demo5: Promise 间隔输入: async 实现的 sleep 来实现</h4>
              <Button type="primary"onClick={this.handleDemo5}>demo5:</Button>
            </div>
            <div>
              <h4>测试demo51: Promise 间隔输入: async 使用的不同地方</h4>
              <Button type="primary"onClick={this.handleDemo51}>demo51:</Button>
            </div>
            <div>
              <h4>测试demo6: Promise 间隔输入: async 实现的 sleep 来实现</h4>
              <Button type="primary"onClick={this.handleDemo6}>demo6:</Button>
            </div>
          </Card>
        </Col>
      </Row>
    );
  }
}
